package com.scalar.chiptrack.adaptor.ikanos.silterra;

import com.scalar.chiptrack.utils.Logger;
import com.scalar.chiptrack.utils.StringUtils;
import com.scalar.chiptrack.adaptor.dao.FabSortAdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.ShippedLotDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;

import com.scalar.chiptrack.adaptor.FabSortLot;
import com.scalar.chiptrack.adaptor.ShippedLot;
import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.db.DBTransaction;
import com.scalar.ScalarException;

import java.util.HashMap;
import java.util.ArrayList;
import java.util.Iterator;
import java.io.File;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;

/**
 * Created by IntelliJ IDEA.
 * User: Sudhakar
 * Date: Aug 30, 2006
 * Time: 12:09:22 AM
 */
public class SilterraDataParser extends JobHandler implements AdaptorConstants
{
    private HashMap<String, FabSortLot> m_wipDataMap   = new HashMap<String, FabSortLot>();
    private HashMap<String, ShippedLot> m_shipDataMap  = new HashMap<String, ShippedLot>();
    private static Logger m_parserLogger    = null;
    private String m_dataOutputDir          = null;
    DBTransaction dbTransaction             = null;

    public SilterraDataParser() throws ScalarException
    {
        try
        {
            m_dataOutputDir = AdaptorUtils.getDataOutputDir( VENDOR_NAME_SILTERRA, WIP_TYPE_FAB );
            if ( m_dataOutputDir != null )
            {
                AdaptorUtils.makeAllAdaptorDirs( m_dataOutputDir );
                
                m_parserLogger = AdaptorUtils.getDataParserLogger( m_dataOutputDir, VENDOR_NAME_SILTERRA );
                FabSortAdaptorDAO.setLogger( m_parserLogger );   // All the DAOs and Parser should be logging into same file
                ShippedLotDAO.setLogger(m_parserLogger);
                AdaptorUtils.setLogger( m_parserLogger );
            }
        }
        catch (ScalarException se) {
            log("ERROR!! ERROR!! ERROR!! Exception while loading Silterra WIP output directory details from database, Exception: " + se);
            throw se;
        }
    }

    public static void main(String args[]) throws Exception
    {
        new SilterraDataParser().execute();
    }

    /**
     *
     * @throws Exception
     */
    public void execute() throws Exception
    {
        AdaptorUtils.printHeader( VENDOR_NAME_SILTERRA, CONSTANT_PARSER );

        File doneDestDir = new File( m_dataOutputDir + "/done" );
        File dataoutDir  = new File( m_dataOutputDir );

        File[] fileList = dataoutDir.listFiles();

        if ( ( fileList == null ) || (fileList.length <= 3))
        {
            log("No file found in directory: " + dataoutDir);
            System.out.println("No file found in directory: " + dataoutDir );
            throw new ScalarException("No file found in directory: " + dataoutDir+ "----\n\n" );
        }
        
        String fileName             = null;
        String tempName             = null;
        ArrayList m_wipList         = null;
        ArrayList m_shipList        = null;
        ArrayList successFileList   = new ArrayList();
        boolean success             = true;
        FileReader reader           = null;

        try
        {
            for (int i = 0; i < fileList.length; i++)
            {
                if (fileList[i].isDirectory() == true)
                {
                    continue;
                }
                tempName = fileList[i].getName();
                fileName = fileList[i].getAbsolutePath();

                if ((tempName != null) && (tempName.trim().startsWith(SilterraAdaptor.FILE_NAME_WIP_STATUS)))
                {
                    try
                    {
                        m_wipList = parseWipInfo(fileName);
                        if (m_wipList != null)
                        {
                            getWipList(m_wipList);
                        }
                        //Add files to success list to move to /done directory
                        successFileList.add(fileList[i]);
                    }
                    catch (Exception e)
                    {
                        success = false;
                        log("Exception while parsing and storing file: " + fileName + "\nException: " + e);
                        e.printStackTrace();
                        throw e;
                    }
                }
                if ((tempName != null) && (tempName.trim().startsWith(SilterraAdaptor.FILE_NAME_SHIP_STATUS)))
                {

                    System.out.println("\nFound " + fileName);
                    System.out.println("Parsing the file for SHIP Information...");
                    log("\nFound " + fileName);
                    log("Parsing the file for SHIP Information...");

                    reader = new FileReader( fileName );

                    SilterraShipParser silterraShipParser = new SilterraShipParser();
                    m_shipList = silterraShipParser.parse( reader );
                    SilterraShipInfo silterraShipInfo = null;

                    try
                    {
                        if ( m_shipList != null  )
                        {
                            Iterator iterator = m_shipList.iterator();
                            while( iterator.hasNext() )
                            {
                               silterraShipInfo = ( SilterraShipInfo ) iterator.next();
                               getShipInfo( silterraShipInfo );
                            }
                            System.out.println("Done parsing..");
                        }

                        try
                        {
                            if ( reader != null )
                            {
                                reader.close();
                                reader = null;
                            }
                        }
                        catch(IOException ignore)
                        {

                        }
                        //Add files to success list to move to /done directory
                        successFileList.add(fileList[i]);
                    }
                    catch (Exception e)
                    {
                        success = false;
                        log("Exception while parsing and storing file: " + fileName + "\nException: " + e);
                        e.printStackTrace();
                        throw e;
                    }
                }
            }
        }
        catch (Exception e)
        {
            success = false;
            log("ERROR!! ERROR!! ERROR!! While parsing and storing File " + e);
            e.printStackTrace();
            throw e;
        }

        // to save the Fab lot tables
        // Start transaction 3
        try
        {
            if ( m_wipDataMap.isEmpty() == false )
            {
                log("Updating Fab Lot Information");
                FabSortAdaptorDAO.saveFabLot(null, m_wipDataMap.values().iterator(),WIP_TYPE_FAB, VENDOR_NAME_SILTERRA);
            }
            else
            {
                 FabSortAdaptorDAO.closeFabSortLot(null,WIP_TYPE_FAB, VENDOR_NAME_SILTERRA);
            }
        }
        catch (Exception e)
        {
            success = false;
            log("ERROR!! ERROR!! ERROR!! Could not update Fab Data information into database: " + e);
            e.printStackTrace();
            throw e;
        }
        // Save shipping info
        // Start transaction 4
        try
        {
            if (m_shipDataMap.isEmpty() == false)
            {
                log("Updating shipment Information");
                ShippedLotDAO.saveShippedLot( dbTransaction, m_shipDataMap.values().iterator());
            }
        }
        catch (Exception e)
        {
            success = false;
            log("ERROR!! ERROR!! ERROR!! Could not update SILTERRA Shipping information into database: " + e);
            e.printStackTrace();
            throw e;
        }

        AdaptorDAO.closeDropOutLots( VENDOR_NAME_SILTERRA );
        
        // TO SEND THE NEW LOTS, NEW TRANSIT LOTS, NO PO LOTS, DISCREPANCY LOTS NOTIFICATIONS TO THE USER
        AdaptorDAO.sendAllNotifications( VENDOR_NAME_SILTERRA, true, true, true );


        int adaptor_id = AdaptorRunInfo.getLastRunAdaptorId( SilterraAdaptor.ADAPTOR_NAME, CONSTANT_ADAPTOR);
        // Update Adaptor_Run_Info table
        try
        {
            if ( success == true )
            {
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, SilterraAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
                System.out.println( "SUCCESSFULLY UPDATED IN THE DATABASE" );
            }
        }
        catch ( ScalarException se )
        {
            success = false; //As filES DATA SAVED , UPDATEING AS SUCCESS
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, SilterraAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
            log( "WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se );
            throw se;
        }

       // Step 7
       // Move the successful files to 'done' directory
       if ( success )
       {
           AdaptorUtils.moveFilesToDone( successFileList, doneDestDir );
       }
    }

    /**
     * Reads, parses the file and saves into database
     */
    private ArrayList parseWipInfo(String fileName) throws Exception
    {
        if (fileName == null) throw new ScalarException("Filename argument is null");

        ArrayList wipInfoList = new ArrayList();
        BufferedReader fileReader = null;

        try
        {
            File wipInfoFile = new File(fileName);
            if (wipInfoFile.exists() == false)
            {
                throw new ScalarException(fileName + " doesnt exist");
            }

            System.out.println("Found " + fileName);
            System.out.println("Parsing the file for Wip Information...");

            fileReader = new BufferedReader(new FileReader(wipInfoFile));

            String line             = null;
            SilterraWipInfo wipInfo = null;

            fileReader.readLine();  // skip 1st line
            fileReader.readLine();  // skip 2nd line

            while ((line = fileReader.readLine()) != null)
            {
                try
                {
                    wipInfo = parseWipInfoLine(line);
                }
                catch (Exception pe)
                {
                    wipInfo = null;
                    pe.getMessage();
                }
                if (wipInfo != null)
                {
                    wipInfoList.add(wipInfo);
                }
            }

            log("Done parsing..");
        }
        finally
        {
            if (fileReader != null)
            {
                try
                {
                    fileReader.close();
                    fileReader = null;
                }
                catch (IOException ignore)
                {
                }
            }
        }
        return wipInfoList;
    }

    /**
     * Parses each line into SILTERRAShippingInfo object
     *
     * @param line to parse
     * @return SILTERRAShippingInfo parsed data object
     * @throws com.scalar.chiptrack.adaptor.ParserException
     *          if there is any problem parsing the line
     */
    private SilterraWipInfo parseWipInfoLine(String line) throws ScalarException
    {
        SilterraWipInfo wipInfo     = null;

        if ((line == null) || (line.startsWith("---")) || (line.trim().length() < 72 /*min length*/))
        {
            return wipInfo;
        }

        try
        {
            line = line.replaceAll( "\"", " " ); // if remove hear it throws exception.
            String[] token = line.split( "," );

            wipInfo = new SilterraWipInfo();

            for (int x = 0; x < token.length; x++)
            {
                if (token[x] != null && token[x].trim().length() > 0)
                {
                    switch (x)
                    {
                        case 0:
                            wipInfo.setTechnology( token[x].trim() );
                            break;
                        case 1:
                            wipInfo.setDevice( token[x].trim() );
                            break;
                        case 2:
                            wipInfo.setLotId( token[x].trim() );
                            break;
                        case 3:
                            wipInfo.setLotType( token[x].trim() );
                            break;
                        case 4:
                            wipInfo.setPriority( token[x].trim() );
                            break;
                        case 5:
                            wipInfo.setStartQty( token[x].trim() );
                            break;
                        case 6:
                            wipInfo.setCurrentQty( token[x].trim() );
                            break;
                        case 7:
                            wipInfo.setPlan( token[x].trim() );
                            break;
                        case 8:
                            wipInfo.setStep( token[x].trim() );
                            break;
                        case 9:
                            wipInfo.setStepSeq( token[x].trim() );
                            break;
                        case 10:
                             wipInfo.setMaskSeq( token[x].trim() );
                            break;
                        case 11:
                             wipInfo.setLotStartDate( token[x].trim() );
                            break;
                        case 12:
                            wipInfo.setOriginalShipDate( token[x].trim() );
                            break;
                        case 13:
                            wipInfo.setProjectedShipDate( token[x].trim() );
                            break;
                        case 14:
                            wipInfo.setSoNumber( token[x].trim() );
                            break;
                        case 15:
                            wipInfo.setPoNUmber( token[x].trim() );
                            break;
                        case 16:
                            wipInfo.setRemarks( token[x].trim() );
                            break;
                    }
                }
            }
        }
        catch (Exception e)
        {
            System.out.println("Exception while parsing Wip Info: " + e);
            System.out.println("Line: " + line);
            throw new ScalarException("Exception while parsing Wip Info: " + e + "\nLine: " + line, e);
        }
        return wipInfo;
    }

    /**
     * @param wipdataList
     */
    public void getWipList(ArrayList wipdataList) throws Exception
    {
        SilterraWipInfo silterraWipReport   = null;
        String partNumber                   = null;
        String lotNumber                    = null;
        FabSortLot fabSortLot               = null;

        Iterator iterator = wipdataList.iterator();
        while (iterator.hasNext())
        {
            silterraWipReport = ( SilterraWipInfo ) iterator.next();

            if (silterraWipReport != null)
            {
                partNumber = silterraWipReport.getDevice();
                lotNumber = silterraWipReport.getLotId();

                if( lotNumber != null && partNumber != null )
                {
                    fabSortLot = (FabSortLot) m_wipDataMap.get(partNumber + lotNumber);
                    if (fabSortLot == null)
                    {
                        fabSortLot = new FabSortLot( VENDOR_NAME_SILTERRA, WIP_TYPE_FAB );
                        m_wipDataMap.put(partNumber + lotNumber, fabSortLot);
                    }
                    int quantity = 0;
                    if (fabSortLot.getQtyIn() != null)
                    {
                        try
                        {
                            quantity = Integer.parseInt(fabSortLot.getQtyIn());
                        }
                        catch (NumberFormatException ignore)
                        {
                        }
                        try
                        {
                            quantity += Integer.parseInt( silterraWipReport.getCurrentQty() );
                        }
                        catch (NumberFormatException ignore)
                        {
                        }
                    }
                    else
                    {
                        try
                        {

                            quantity = Integer.parseInt( silterraWipReport.getCurrentQty() );
                        }
                        catch (NumberFormatException ignore)
                        {
                        }
                    }

                    String dateIn           = null;
                    String expectedDateOut  = null;
                    String outLookDate      = null;
                   
                    if( silterraWipReport.getLotStartDate() != null && silterraWipReport.getLotStartDate().trim().length() > 0 )
                    {
                          dateIn = StringUtils.formatDate ( silterraWipReport.getLotStartDate(), "yyyy-MMM-dd", "MM/dd/yyyy");
                    }
                    if( silterraWipReport.getOriginalShipDate() != null &&  silterraWipReport.getOriginalShipDate().trim().length() > 0 )
                    {
                          expectedDateOut = StringUtils.formatDate( silterraWipReport.getOriginalShipDate(), "yyyy-MMM-dd", "MM/dd/yyyy");
                    }

                    if( silterraWipReport.getProjectedShipDate() != null && silterraWipReport.getProjectedShipDate().trim().length() > 0 )
                    {
                            outLookDate = StringUtils.formatDate( silterraWipReport.getProjectedShipDate(), "yyyy-MMM-dd", "MM/dd/yyyy");
                    }


                    if( quantity > 0 && quantity <= 25)
                    {

                           fabSortLot.setProcessGen( silterraWipReport.getTechnology() );

                           fabSortLot.setWsQty ( silterraWipReport.getStartQty());
                           fabSortLot.setSoNumber( silterraWipReport.getSoNumber() );
                           fabSortLot.setPriorty( silterraWipReport.getPriority());
                           fabSortLot.setLayerPosition ( silterraWipReport.getMaskSeq() );
                           fabSortLot.setShip_fcst_date( expectedDateOut );
                           fabSortLot.setShip_conf_date( outLookDate );

                        fabSortLot.setLotId( lotNumber);
                        fabSortLot.setCustProduct( partNumber);
                        fabSortLot.setDateIn( dateIn );
                        fabSortLot.setQtyIn( quantity + "");
                        fabSortLot.setStage( silterraWipReport.getStep() );
                        fabSortLot.setStagePosition( silterraWipReport.getStepSeq() );
                        fabSortLot.setLotStatus( LOT_STATUS_RUNNING );
                        fabSortLot.setPoNumber( silterraWipReport.getPoNUmber() );
                        fabSortLot.setVendorLot( lotNumber );
                        fabSortLot.setForcastedDateOut( expectedDateOut );
                        fabSortLot.setOutLookDate( outLookDate );

                        if ( silterraWipReport.getLotType() != null && ("ENX".equalsIgnoreCase(silterraWipReport.getLotType().trim() ) == true || "PRT".equalsIgnoreCase(silterraWipReport.getLotType().trim()) == true
                         || "PRA".equalsIgnoreCase( silterraWipReport.getLotType()) == true ))
                        {
                           fabSortLot.setLotCategory( LOT_CATEGORY_TYPE_ENGG );
                        }
                        else
                        {
                            fabSortLot.setLotCategory( LOT_CATEGORY_TYPE_PROD );
                        }

                    }
                }
            }
        }
    }

    /**
     * @param shipInfo
     */
    private void getShipInfo( SilterraShipInfo shipInfo) throws Exception
    {

        ShippedLot shippedLot   = null;
        String partNumber       = null;
        String lotNumber        = null;
        String invoiceNo        = null;
        String shipDate         = null;

        partNumber  = shipInfo.getCustomerDeviceID();
        lotNumber   = shipInfo.getFwLotID();
        shipDate    = shipInfo.getShipmentDate();

        if (lotNumber != null && lotNumber.length() > 0)
        {
            shippedLot = (ShippedLot) m_shipDataMap.get(lotNumber + partNumber + shipDate + shipInfo.getPoNumber());

            if (shippedLot == null)
            {
                shippedLot = new ShippedLot( VENDOR_NAME_SILTERRA, WIP_TYPE_FAB );
                m_shipDataMap.put(lotNumber + partNumber + invoiceNo + shipDate + shipInfo.getPoNumber(), shippedLot);
            }
            int quantity = 0;
            if (shippedLot.getShipQty() != null)
            {
                try
                {
                    quantity = Integer.parseInt(shippedLot.getShipQty());
                }
                catch (NumberFormatException ignore)
                {
                }
                try
                {
                    quantity += Integer.parseInt(shipInfo.getQuantity());
                }
                catch (NumberFormatException ignore)
                {
                }
            }
            else
            {
                try
                {
                    quantity = Integer.parseInt(shipInfo.getQuantity());
                }
                catch (NumberFormatException ignore)
                {
                }
            }
            if (shipDate != null && shipDate.trim().length() > 0)
            {
                shipDate = StringUtils.formatDate(shipDate, "dd-MMM-yyyy", "MM/dd/yyyy");
            }
            if ( quantity > 0 )
            {
                shippedLot.setLotNumber(lotNumber);
                shippedLot.setPartNumber(partNumber);
                shippedLot.setFabLotNumber( lotNumber );
                shippedLot.setShipDate(shipDate);
                shippedLot.setShipQty(quantity + "");
                shippedLot.setInvoiceNumber(shipInfo.getInvoiceNumber());
                shippedLot.setCustomerPO(shipInfo.getPoNumber());
                shippedLot.setShippingDoc( shipInfo.getShipmentNumber() );
            }    
        }
    }
    /**
     * @param message
     */
    private static void log(String message)
    {

        if (message == null) return;

        if (m_parserLogger != null) {
            synchronized (m_parserLogger)
            {
                m_parserLogger.logDebug(message + LINE_SEPARATOR);
            }
        }
        else
        {
            System.out.println(message);
        }
    }
}
